/**
 * Copyright &copy; 2017 <a href="https://gitee.com/hackempire/emsite-parent">emsite</a> All rights reserved.
 */
package com.empire.emsite.modules.sys.utils;

import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;

import com.empire.emsite.common.utils.CacheUtils;
import com.empire.emsite.common.utils.SpringContextHolder;
import com.empire.emsite.modules.sys.entity.Area;
import com.empire.emsite.modules.sys.entity.Menu;
import com.empire.emsite.modules.sys.entity.Office;
import com.empire.emsite.modules.sys.entity.Role;
import com.empire.emsite.modules.sys.entity.User;
import com.empire.emsite.modules.sys.facade.AreaFacadeService;
import com.empire.emsite.modules.sys.facade.OfficeFacadeService;
import com.empire.emsite.modules.sys.facade.SystemFacadeService;
import com.empire.emsite.modules.sys.security.SystemAuthorizingRealm.Principal;

/**
 * 类UserUtils.java的实现描述：用户工具类
 * 
 * @author arron 2017年10月30日 下午7:20:40
 */
public class UserUtils {
    private static SystemFacadeService systemService                 = SpringContextHolder
                                                                             .getBean(SystemFacadeService.class);
    private static AreaFacadeService   areaService                   = SpringContextHolder
                                                                             .getBean(AreaFacadeService.class);
    private static OfficeFacadeService officeService                 = SpringContextHolder
                                                                             .getBean(OfficeFacadeService.class);

    public static final String         USER_CACHE                    = "userCache";
    public static final String         USER_CACHE_ID_                = "id_";
    public static final String         USER_CACHE_LOGIN_NAME_        = "ln";
    public static final String         USER_CACHE_LIST_BY_OFFICE_ID_ = "oid_";

    public static final String         CACHE_AUTH_INFO               = "authInfo";
    public static final String         CACHE_ROLE_LIST               = "roleList";
    public static final String         CACHE_MENU_LIST               = "menuList";
    public static final String         CACHE_AREA_LIST               = "areaList";
    public static final String         CACHE_OFFICE_LIST             = "officeList";
    public static final String         CACHE_OFFICE_ALL_LIST         = "officeAllList";
    public static final String         CACHE_CATEGORY_LIST           = "categoryList";

    /**
     * 根据ID获取用户
     * 
     * @param id
     * @return 取不到返回null
     */
    public static User get(String id) {
        User user = (User) CacheUtils.get(USER_CACHE, USER_CACHE_ID_ + id);
        if (user == null) {
            user = systemService.getUser(id);
            if (user == null) {
                return null;
            }
            user.setRoleList(systemService.findRole(new Role(user)));
            CacheUtils.put(USER_CACHE, USER_CACHE_ID_ + user.getId(), user);
            CacheUtils.put(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getLoginName(), user);
        }
        return user;
    }

    /**
     * 根据登录名获取用户
     * 
     * @param loginName
     * @return 取不到返回null
     */
    public static User getByLoginName(String loginName) {
        User user = (User) CacheUtils.get(USER_CACHE, USER_CACHE_LOGIN_NAME_ + loginName);
        if (user == null) {
            user = systemService.getUserByLoginName(loginName);
            if (user == null) {
                return null;
            }
            user.setRoleList(systemService.findRole(new Role(user)));
            CacheUtils.put(USER_CACHE, USER_CACHE_ID_ + user.getId(), user);
            CacheUtils.put(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getLoginName(), user);
        }
        return user;
    }

    /**
     * 清除当前用户缓存
     */
    public static void clearCache() {
        removeCache(CACHE_AUTH_INFO);
        removeCache(CACHE_ROLE_LIST);
        removeCache(CACHE_MENU_LIST);
        removeCache(CACHE_AREA_LIST);
        removeCache(CACHE_OFFICE_LIST);
        removeCache(CACHE_OFFICE_ALL_LIST);
        UserUtils.clearCache(getUser());
    }

    /**
     * 清除指定用户缓存
     * 
     * @param user
     */
    public static void clearCache(User user) {
        CacheUtils.remove(USER_CACHE, USER_CACHE_ID_ + user.getId());
        CacheUtils.remove(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getLoginName());
        CacheUtils.remove(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getOldLoginName());
        if (user.getOffice() != null && user.getOffice().getId() != null) {
            CacheUtils.remove(USER_CACHE, USER_CACHE_LIST_BY_OFFICE_ID_ + user.getOffice().getId());
        }
    }

    /**
     * 获取当前用户
     * 
     * @return 取不到返回 new User()
     */
    public static User getUser() {
        Principal principal = getPrincipal();
        if (principal != null) {
            User user = get(principal.getId());
            if (user != null) {
                return user;
            }
            return new User();
        }
        // 如果没有登录，则返回实例化空的User对象。
        return new User();
    }

    /**
     * 获取当前用户角色列表
     * 
     * @return
     */
    public static List<Role> getRoleList() {
        @SuppressWarnings("unchecked")
        List<Role> roleList = (List<Role>) getCache(CACHE_ROLE_LIST);
        if (roleList == null) {
            User user = getUser();
            roleList = systemService.findAllRole(user);
            putCache(CACHE_ROLE_LIST, roleList);
        }
        return roleList;
    }

    /**
     * 获取当前用户授权菜单
     * 
     * @return
     */
    public static List<Menu> getMenuList() {
        @SuppressWarnings("unchecked")
        List<Menu> menuList = (List<Menu>) getCache(CACHE_MENU_LIST);
        if (menuList == null) {
            User user = getUser();
            menuList = systemService.findAllMenu(user);
            putCache(CACHE_MENU_LIST, menuList);
        }
        return menuList;
    }

    /**
     * 获取[*当前用户授权*]系统所有的区域
     * 
     * @return
     */
    public static List<Area> getAreaList() {
        @SuppressWarnings("unchecked")
        List<Area> areaList = (List<Area>) getCache(CACHE_AREA_LIST);
        if (areaList == null) {
            areaList = areaService.findAllList();
            putCache(CACHE_AREA_LIST, areaList);
        }
        return areaList;
    }

    /**
     * 获取当前用户有权限访问的部门
     * 
     * @return
     */
    public static List<Office> getOfficeList() {
        @SuppressWarnings("unchecked")
        List<Office> officeList = (List<Office>) getCache(CACHE_OFFICE_LIST);
        if (officeList == null) {
            User user = getUser();
            officeList = officeService.findAll(user);
            putCache(CACHE_OFFICE_LIST, officeList);
        }
        return officeList;
    }

    /**
     * 获取[*当前用户有权限访问*]所有的部门
     * 
     * @return
     */
    public static List<Office> getOfficeAllList() {
        @SuppressWarnings("unchecked")
        List<Office> officeList = (List<Office>) getCache(CACHE_OFFICE_ALL_LIST);
        if (officeList == null) {
            officeList = officeService.findAllList();
        }
        return officeList;
    }

    /**
     * 获取授权主要对象
     */
    public static Subject getSubject() {
        return SecurityUtils.getSubject();
    }

    /**
     * 获取当前登录者对象
     */
    public static Principal getPrincipal() {
        try {
            Subject subject = SecurityUtils.getSubject();
            Principal principal = (Principal) subject.getPrincipal();
            if (principal != null) {
                return principal;
            }
            //			subject.logout();
        } catch (UnavailableSecurityManagerException e) {

        } catch (InvalidSessionException e) {

        }
        return null;
    }

    public static Session getSession() {
        try {
            Subject subject = SecurityUtils.getSubject();
            Session session = subject.getSession(false);
            if (session == null) {
                session = subject.getSession();
            }
            if (session != null) {
                return session;
            }
            //			subject.logout();
        } catch (InvalidSessionException e) {

        }
        return null;
    }

    // ============== User Cache ==============

    public static Object getCache(String key) {
        return getCache(key, null);
    }

    public static Object getCache(String key, Object defaultValue) {
        //		Object obj = getCacheMap().get(key);
        Object obj = getSession().getAttribute(key);
        return obj == null ? defaultValue : obj;
    }

    public static void putCache(String key, Object value) {
        //		getCacheMap().put(key, value);
        getSession().setAttribute(key, value);
    }

    public static void removeCache(String key) {
        //		getCacheMap().remove(key);
        getSession().removeAttribute(key);
    }

    //	public static Map<String, Object> getCacheMap(){
    //		Principal principal = getPrincipal();
    //		if(principal!=null){
    //			return principal.getCacheMap();
    //		}
    //		return new HashMap<String, Object>();
    //	}

}
